package view;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;

/**
 * Superclass to all view Panels. Contains all 
 * behavior that is in common with all view panels
 * including style, and most importantly the 
 * controller object.
 * 
 * @author Tristan D. Boucher
 * @version Commit #22 9/14/2013
 *
 */
@SuppressWarnings("serial")
public abstract class AbstractView extends JPanel implements ViewInterface
{
  /**
   * The constant color for the background of components.
   */
  protected static final Color BACKGROUND_COLOR = Color.CYAN.darker();
  
  /**
   * The constant color for the titled border font on BACKGROUND_COLOR.
   */
  protected static final Color TEXT_FIELD_BORDER_COLOR = Color.GREEN;
  
  /**
   * The constant color for the lined borders.
   */
  protected static final Color LINED_BORDER_COLOR = Color.BLACK;
  
  /**
   * The Font type used in this gui.
   */
  protected static final String FONT = "Veranda";
  
  /**
   * The MVC controller object needed for all 
   * views to report to.
   */
  protected final GUIController my_controller;
 
  /**
   * The Width of this Panel.
   */
  protected final int my_width;

  /**
   * The Height of this Panel.
   */
  protected final int my_height;
  
  /**
   * Constructs and processes the view object.
   * 
   * @param the_controller The controller object for this
   * view.
   * @param the_width The width passed in for this view.
   * @param the_height The height passed in for this view.
   */
  public AbstractView(final GUIController the_controller,
                      final int the_width,
                      final int the_height)
  {
    super();
    
    my_width = the_width;
    my_height = the_height;
    my_controller = the_controller;
  }
  
  //Accessor methods
  /**
   * Returns the preferred size of this Panel as a dimension.
   * 
   * @return the dimension of this component.
   */
  public Dimension getSize()
  {
    return new Dimension(my_width, my_height);
  }
  
  /**
   * Easilly adds a background color on construction of the component.
   * 
   * @param the_component The component to have its background colored.
   * @param the_color The color of the background for the component.
   * 
   * @return The modified component.
   */
  protected JComponent addBackground(final JComponent the_component,
                                   final Color the_color)
  {
    the_component.setBackground(the_color);
    return the_component;
  }
  
  /**
   * Adds a border to any component. Adds look and feel and user friendliness.
   * 
   * @param the_component The component to be bordered.
   * @param the_title The title for the titled border.
   * @param the_border_text_color The color of the text that the titled border displays.
   * @param the_font_size The integer for the size of the font in the titled border.
   * @return the bordered component. 
   */
  protected JComponent addTitledBorder(final JComponent the_component, 
                               final String the_title,
                               final Color the_border_text_color,
                               final int the_font_size)
  {
    the_component.setBorder(BorderFactory.createTitledBorder(
      BorderFactory.createLineBorder(LINED_BORDER_COLOR, 2, true),
      the_title, 
      SwingConstants.LEFT, 
      SwingConstants.LEFT, 
      new Font(FONT, Font.ITALIC, the_font_size), 
      the_border_text_color));
    return the_component;
  }
  
  /**
   * Adds and returns the component passed with a new line border. Adds look and feel.
   * 
   * @param the_component The component to be line bordered.
   * @param the_border_color The color of the line border to be added.
   * 
   * @return The component passed with an added border.
   */
  protected JComponent addLinedBorder(final JComponent the_component,
                                      final Color the_border_color)
  {
    the_component.setBorder(BorderFactory.createLineBorder(the_border_color, 2, true));
    return the_component;
  }
  
  //Static methods
  /**
   * This static factory method recieves an array of Strings
   * and from that list, generates a list of JLabels following
   * the look and feel of this gui. Only extending classes may
   * use this as to keep the general look and feel consistant.
   * 
   * @param the_messages The text used in the JLabels construction.
   * @return a JLabel array constructed from the strings passed.
   */
  protected static JLabel[] createLabelsArray(final String[] the_messages)
  {
    final JLabel[] labels = new JLabel[the_messages.length];

    for (int i = 0; i < the_messages.length; i++)
    {
      labels[i] = new JLabel(the_messages[i]);
      labels[i].setFont(new Font("Times New Roman", Font.BOLD, FIELD_LENGTH));
      labels[i].setForeground(Color.BLUE);
    }

    return labels;
  }

  /**
   * Creates an array of JTextFields with the array of strings that is passed
   * and uses those strings as titled borders to surround the text box and
   * contribute to the look and feel.
   * @param the_n The number of fields. Useful in increasing or decreasing number
   * of fields easilly. (initially thought to allow each field to show up only 
   * after the last had been completed by increasing the field count. but 
   * that idea never came to fruition.)
   * 
   * @param the_labels The titles for the titled borders. descriptions of the 
   * fields.
   * @return An array of JTextFields; each wrapped in a descriptive border.
   */
  protected static JTextField[] createFieldsArray(final int the_n, 
                                                  final String[] the_labels)
  {
    final JTextField[] text_fields = new JTextField[the_n];

    for (int i = 0; i < the_n; i++)
    {
      text_fields[i] = new JTextField(FIELD_LENGTH);
      //addBorder(text_fields[i], the_labels[i]);
      text_fields[i].setPreferredSize(new Dimension(0,45));
      text_fields[i].setHorizontalAlignment(SwingConstants.CENTER);
      text_fields[i].setBackground(Color.CYAN.darker());
    }

    return text_fields;
  }

  /**
   * Creates an array of JTextFields filled with the given
   * text. This gui is mostly a factory type and therefore
   * in order to have auto-fill constructors this was helpful.
   * 
   * @param the_n The number of Components to make.(easy
   * to restrict and change.)
   * @param the_fill The text that will be inserted into the
   * fields in the array.
   * @param the_labels The strings that are used in the borders.
   * 
   * @return A JTextField array consistent with the look and feel.
   */
  protected static JTextField[] createFieldsArray(final int the_n,
                                                  final String[] the_fill,
                                                  final String[] the_labels)
  {
    final JTextField[] text_fields = new JTextField[the_n];

    for (int i = 0; i < the_n; i++)
    {
      text_fields[i] = new JTextField(FIELD_LENGTH);
      text_fields[i].setText(the_fill[i]);

    }

    return text_fields;
  }

  /**
   * Creates a n array of buttons consistent with the look and feel.
   * 
   * @param the_messages The text to create the buttons with.
   * 
   * @return An array of JButtons consitent with the look and feel.
   */
  protected  static JButton[] createButtonsArray(final String[] the_messages) 
  {
    final JButton[] buttons = new JButton[the_messages.length];

    for (int i = 0; i < the_messages.length; i++)
    {
      buttons[i] = new JButton(the_messages[i]);
      buttons[i].setBackground(Color.CYAN.darker());
    }

    return buttons;
  }
}
